import 'dart:math';

import 'package:dynamic_theme/helpers/colors.dart';
import 'package:dynamic_theme/helpers/textThemeStyle.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';

class RefreshFooter extends Footer {
  /// Key
  final Key? key;

  /// 方位
  final AlignmentGeometry? alignment;

  /// 提示加载文字
  final String loadText;

  /// 准备加载文字
  final String loadReadyText;

  /// 正在加载文字
  final String loadingText;

  /// 加载完成文字
  final String loadedText;

  /// 加载失败文字
  final String loadFailedText;

  /// 没有更多文字
  final String noMoreText;

  /// 显示额外信息(默认为时间)
  final bool showInfo;

  /// 更多信息
  final String infoText;

  /// 背景颜色
  final Color bgColor;

  /// 字体颜色
  final Color textColor;

  /// 更多信息文字颜色
  final Color infoColor;

  RefreshFooter({
    extent = 60.0,
    triggerDistance = 70.0,
    float = false,
    completeDuration = const Duration(seconds: 1),
    enableInfiniteLoad = true,
    enableHapticFeedback = false,
    this.key,
    this.alignment,
    this.loadText = '拉动加载更多',
    this.loadReadyText = '释放加载',
    this.loadingText = '正在加载中',
    this.loadedText = '加载完成',
    this.loadFailedText = '加载失败',
    this.noMoreText = '看看其它的吧，这里已经没有了',
    this.showInfo = true,
    this.infoText = 'Updated at %T',
    this.bgColor = Colors.transparent,
    this.textColor = Colors.black,
    this.infoColor = Colors.teal,
  }) : super(
          extent: extent as double,
          triggerDistance: triggerDistance as double,
          float: float as bool,
          completeDuration: completeDuration as Duration,
          enableInfiniteLoad: enableInfiniteLoad as bool,
          enableHapticFeedback: enableHapticFeedback as bool,
        );

  @override
  Widget contentBuilder(
    BuildContext context,
    LoadMode loadState,
    double pulledExtent,
    double loadTriggerPullDistance,
    double loadIndicatorExtent,
    AxisDirection axisDirection,
    bool float,
    Duration? completeDuration,
    bool enableInfiniteLoad,
    bool success,
    bool noMore,
  ) =>
      ClassicalFooterWidget(
        key,
        classicalFooter: this,
        loadState: loadState,
        pulledExtent: pulledExtent,
        loadTriggerPullDistance: loadTriggerPullDistance,
        loadIndicatorExtent: loadIndicatorExtent,
        axisDirection: axisDirection,
        float: float,
        completeDuration: completeDuration ?? Duration(milliseconds: 300),
        enableInfiniteLoad: enableInfiniteLoad,
        success: success,
        noMore: noMore,
      );
}

/// 经典Footer组件
class ClassicalFooterWidget extends StatefulWidget {
  final RefreshFooter classicalFooter;
  final LoadMode loadState;
  final double pulledExtent;
  final double loadTriggerPullDistance;
  final double loadIndicatorExtent;
  final AxisDirection axisDirection;
  final bool float;
  final Duration completeDuration;
  final bool enableInfiniteLoad;
  final bool success;
  final bool noMore;

  const ClassicalFooterWidget(
    Key? key, {
    required this.loadState,
    required this.classicalFooter,
    required this.pulledExtent,
    required this.loadTriggerPullDistance,
    required this.loadIndicatorExtent,
    required this.axisDirection,
    required this.float,
    required this.completeDuration,
    required this.enableInfiniteLoad,
    required this.success,
    required this.noMore,
  }) : super(key: key);

  @override
  ClassicalFooterWidgetState createState() => ClassicalFooterWidgetState();
}

class ClassicalFooterWidgetState extends State<ClassicalFooterWidget>
    with TickerProviderStateMixin<ClassicalFooterWidget> {
  // 是否到达触发加载距离
  bool _overTriggerDistance = false;
  bool get overTriggerDistance => _overTriggerDistance;
  set overTriggerDistance(bool over) {
    if (_overTriggerDistance != over) {
      _overTriggerDistance
          ? _readyController.forward()
          : _restoreController.forward();
    }
    _overTriggerDistance = over;
  }

  // 动画
  late AnimationController _readyController;
  late Animation<double> _readyAnimation;
  late AnimationController _restoreController;
  late Animation<double> _restoreAnimation;

  // Icon旋转度
  double _iconRotationValue = 1.0;

  // 显示文字
  String get _showText {
    if (widget.noMore) return widget.classicalFooter.noMoreText;
    if (widget.enableInfiniteLoad) {
      if (widget.loadState == LoadMode.loaded ||
          widget.loadState == LoadMode.inactive ||
          widget.loadState == LoadMode.drag) {
        return widget.classicalFooter.loadedText;
      } else {
        return widget.classicalFooter.loadingText;
      }
    }
    switch (widget.loadState) {
      case LoadMode.load:
        return widget.classicalFooter.loadingText;
      case LoadMode.armed:
        return widget.classicalFooter.loadingText;
      case LoadMode.loaded:
        return _finishedText;
      case LoadMode.done:
        return _finishedText;
      default:
        if (overTriggerDistance) {
          return widget.classicalFooter.loadReadyText;
        } else {
          return widget.classicalFooter.loadText;
        }
    }
  }

  // 加载结束文字
  String get _finishedText {
    if (!widget.success) return widget.classicalFooter.loadFailedText;
    if (widget.noMore) return widget.classicalFooter.noMoreText;
    return widget.classicalFooter.loadedText;
  }

  // 加载结束图标
  IconData get _finishedIcon {
    if (!widget.success) return Icons.error_outline;
    if (widget.noMore) return Icons.inbox;
    return Icons.done;
  }

  @override
  void initState() {
    super.initState();
    // 初始化动画
    _readyController = AnimationController(
        duration: const Duration(milliseconds: 200), vsync: this);
    _readyAnimation = Tween(begin: 0.5, end: 1.0).animate(_readyController)
      ..addListener(() {
        setState(() {
          if (_readyAnimation.status != AnimationStatus.dismissed) {
            _iconRotationValue = _readyAnimation.value;
          }
        });
      });
    _readyAnimation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _readyController.reset();
      }
    });
    _restoreController = AnimationController(
        duration: const Duration(milliseconds: 200), vsync: this);
    _restoreAnimation = Tween(begin: 1.0, end: 0.5).animate(_restoreController)
      ..addListener(() {
        setState(() {
          if (_restoreAnimation.status != AnimationStatus.dismissed) {
            _iconRotationValue = _restoreAnimation.value;
          }
        });
      });
    _restoreAnimation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _restoreController.reset();
      }
    });
  }

  @override
  void dispose() {
    _readyController.dispose();
    _restoreController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 是否为垂直方向
    var isVertical = widget.axisDirection == AxisDirection.down ||
        widget.axisDirection == AxisDirection.up;
    // 是否反向
    var isReverse = widget.axisDirection == AxisDirection.up ||
        widget.axisDirection == AxisDirection.left;
    // 是否到达触发加载距离
    overTriggerDistance = widget.loadState != LoadMode.inactive &&
        widget.pulledExtent >= widget.loadTriggerPullDistance;
    return Stack(
      clipBehavior: Clip.none,
      children: <Widget>[
        Positioned(
          top: !isVertical
              ? 0.0
              : !isReverse
                  ? 0.0
                  : null,
          bottom: !isVertical
              ? 0.0
              : isReverse
                  ? 0.0
                  : null,
          left: isVertical
              ? 0.0
              : !isReverse
                  ? 0.0
                  : null,
          right: isVertical
              ? 0.0
              : isReverse
                  ? 0.0
                  : null,
          child: Container(
            alignment: (widget.classicalFooter.alignment ?? isVertical) as bool
                ? !isReverse
                    ? Alignment.topCenter
                    : Alignment.bottomCenter
                : isReverse
                    ? Alignment.centerRight
                    : Alignment.centerLeft,
            width: !isVertical
                ? widget.loadIndicatorExtent > widget.pulledExtent
                    ? widget.loadIndicatorExtent
                    : widget.pulledExtent
                : double.infinity,
            height: isVertical
                ? widget.loadIndicatorExtent > widget.pulledExtent
                    ? widget.loadIndicatorExtent
                    : widget.pulledExtent
                : double.infinity,
            color: widget.classicalFooter.bgColor,
            child: SizedBox(
              height: isVertical
                  ? widget.loadIndicatorExtent - 15
                  : double.infinity,
              width: !isVertical ? widget.loadIndicatorExtent : double.infinity,
              child: isVertical
                  ? Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: _buildContent(isVertical, isReverse),
                    )
                  : Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: _buildContent(isVertical, isReverse),
                    ),
            ),
          ),
        ),
      ],
    );
  }

  // 构建显示内容
  List<Widget> _buildContent(bool isVertical, bool isReverse) => isVertical
      ? <Widget>[
          Container(
            alignment: Alignment.centerRight,
            padding: EdgeInsets.only(
              right: 10.0,
            ),
            child: (widget.loadState == LoadMode.load ||
                        widget.loadState == LoadMode.armed) &&
                    !widget.noMore
                ? SizedBox(
                    width: 16.0,
                    height: 16.0,
                    child: CircularProgressIndicator(
                      backgroundColor: Color(0xffff4b6e),
                      valueColor: AlwaysStoppedAnimation(Color(0xff0096fa)),
                    ),
                  )
                : widget.loadState == LoadMode.loaded ||
                        widget.loadState == LoadMode.done ||
                        (widget.enableInfiniteLoad &&
                            widget.loadState != LoadMode.loaded) ||
                        widget.noMore
                    ? SizedBox()
                    : Transform.rotate(
                        angle: 2 * pi * _iconRotationValue,
                        child: Icon(
                          !isReverse
                              ? Icons.arrow_upward
                              : Icons.arrow_downward,
                          color: widget.classicalFooter.textColor,
                        ),
                      ),
          ),
          Text(
            _showText,
            style: TextThemeStyle.of(context)
                .font12!
                .copyWith(color: ColorTheme.of(context).cubeColor),
          ),
        ]
      : <Widget>[
          Container(
            child: widget.loadState == LoadMode.load ||
                    widget.loadState == LoadMode.armed
                ? Container(
                    width: 20.0,
                    height: 20.0,
                    child: CircularProgressIndicator(
                      strokeWidth: 2.0,
                      valueColor: AlwaysStoppedAnimation(
                        widget.classicalFooter.textColor,
                      ),
                    ),
                  )
                : widget.loadState == LoadMode.loaded ||
                        widget.loadState == LoadMode.done ||
                        (widget.enableInfiniteLoad &&
                            widget.loadState != LoadMode.loaded) ||
                        widget.noMore
                    ? Icon(
                        _finishedIcon,
                        color: widget.classicalFooter.textColor,
                      )
                    : Transform.rotate(
                        angle: 2 * pi * _iconRotationValue,
                        child: Icon(
                          !isReverse ? Icons.arrow_back : Icons.arrow_forward,
                          color: widget.classicalFooter.textColor,
                        ),
                      ),
          ),
        ];
}
